//-----------------------------------------------------------------------
// <copyright file="Parameters.cs" company="Microsoft">
// This should contain the copyright text
// </copyright>
// <summary>This contains the class for managing the command line parameters</summary>
// <author>Kimmo Forss</author>
//-----------------------------------------------------------------------

namespace SharePointImporter.CommandLine
{
    using System;
    using System.Globalization;
    using SharePoint.ImportExport.Core;

    /// <summary>
    /// This is the parameters class
    /// </summary>
    internal class Parameters
    {
        /// <summary>
        /// This is the flag that controls if sites need to be created or if the migration can proceed directly
        /// </summary>
        private bool bypass = false;

        /// <summary>
        /// This is the directory name containing the struct.xml file
        /// </summary>
        private string directoryName = string.Empty;

        /// <summary>
        /// This is the URL to the site collection
        /// </summary>
        private string webApplicationURL = string.Empty;

        /// <summary>
        /// This is the managed path to be used when importing
        /// </summary>
        private string managedPath = string.Empty;

        /// <summary>
        /// This is the Site name
        /// </summary>
        private string siteName = string.Empty;

        /// <summary>
        /// This controls whether or not if user information is imported
        /// </summary>
        private bool setSecurity = false;

        /// <summary>
        /// This contols if import to already existing sites is allowed
        /// </summary>
        private bool allowImportToExistingSites = false;

        /// <summary>
        /// This contols if import to already existing lists is allowed
        /// </summary>
        private bool allowImportToExistingLibraries = false;

        /// <summary>
        /// This contols if the xml schema will be validated
        /// </summary>
        private bool checkSchema = false;

        /// <summary>
        /// This specifies the error reporting threshold
        /// </summary>
        private ErrorLevel reportLevel = ErrorLevel.Information;

        /// <summary>
        /// This is the name of the site definition to use
        /// </summary>
        private string siteDefinitionName;

        /// <summary>
        /// This is the site collection owner
        /// </summary>
        private string owner;

        /// <summary>
        /// This is the email of the owner a
        /// </summary>
        private string contact;


        /// <summary>
        /// Initializes a new instance of the Parameters class.
        /// </summary>
        public Parameters()
        {
        }

        /// <summary>
        /// Gets or sets the reporting level
        /// </summary>
        public ErrorLevel ReportLevel
        {
            get
            {
                return this.reportLevel;
            }

            set
            {
                this.reportLevel = value;
            }
        }

        /// <summary>
        /// Gets or sets the directory
        /// </summary>
        public string DirectoryName
        {
            get
            {
                return this.directoryName;
            }

            set
            {
                this.directoryName = value;
            }
        }

        /// <summary>
        /// Gets or sets the contact
        /// </summary>
        public string Contact
        {
            get
            {
                return this.contact;
            }

            set
            {
                this.contact = value;
            }
        }

        /// <summary>
        /// Gets or sets the site definition
        /// </summary>
        public string Sitedefinition
        {
            get
            {
                return this.siteDefinitionName;
            }

            set
            {
                this.siteDefinitionName = value;
            }
        }

        /// <summary>
        /// Gets or sets the owner 
        /// </summary>
        public string Owner
        {
            get
            {
                return this.owner;
            }

            set
            {
                this.owner = value;
            }

        }


        /// <summary>
        /// Gets or sets a value indicating whether	bypass is allowed
        /// </summary>
        public bool Bypass
        {
            get
            {
                return this.bypass;
            }

            set
            {
                this.bypass = value;
            }
        }

        /// <summary>
        /// Gets or sets the Site Collection URL
        /// </summary>
        public string WebApplicationURL
        {
            get
            {
                return this.webApplicationURL;
            }

            set
            {
                this.webApplicationURL = value;
            }
        }

        /// <summary>
        /// Gets or sets the managed path
        /// </summary>
        public string ManagedPath
        {
            get
            {
                return this.managedPath;
            }

            set
            {
                this.managedPath = value;
            }
        }

        /// <summary>
        /// Gets or sets the Site name
        /// </summary>
        public string SiteName
        {
            get
            {
                return this.siteName;
            }

            set
            {
                this.siteName = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether or not security information will be imported
        /// </summary>
        public bool SetSecurity
        {
            get
            {
                return this.setSecurity;
            }

            set
            {
                this.setSecurity = value;
            }
        }

        /// <summary>
        ///  Gets or sets a value indicating whether or not the xml files will be validated
        /// </summary>
        public bool CheckSchema
        {
            get
            {
                return this.checkSchema;
            }

            set
            {
                this.checkSchema = value;
            }
        }

        /// <summary>
        ///  Gets or sets a value indicating whether or not importing to already existing sites is allowed
        /// </summary>
        public bool AllowImportToExistingSites
        {
            get
            {
                return this.allowImportToExistingSites;
            }

            set
            {
                this.allowImportToExistingSites = value;
            }
        }

        /// <summary>
        ///  Gets or sets a value indicating whether or not import to already existing list/libraries is allowed
        /// </summary>
        public bool AllowImportToExistingLibraries
        {
            get
            {
                return this.allowImportToExistingLibraries;
            }

            set
            {
                this.allowImportToExistingLibraries = value;
            }
        }

        /// <summary>
        /// This processes the arguments
        /// </summary>
        /// <param name="args">command line arguments</param>
        /// <param name="lastError">output string with error</param>
        /// <returns>true if succeeded</returns>
        public bool ProcessArgs(string[] args, out string lastError)
        {
            bool retValue = true;
            lastError = string.Empty;
            try
            {
                this.AllowImportToExistingSites = this.GetSingleArg(args, "-OKToImportToExistingSite");
                this.AllowImportToExistingLibraries = this.GetSingleArg(args, "-OKToImportToExistingLibrary");
                this.SetSecurity = this.GetSingleArg(args, "-ImportSecurity");
                this.Bypass = this.GetSingleArg(args, "-bypass");
                this.CheckSchema = this.GetSingleArg(args, "-ValidateXML");
                string stringReportLevel = this.GetArg(args, "-reportLevel", string.Empty);
                if (stringReportLevel.Length > 0)
                {
                    this.ReportLevel = (ErrorLevel)Enum.Parse(typeof(ErrorLevel), stringReportLevel);
                }

                this.WebApplicationURL = this.GetArg(args, "-webApp", string.Empty);
                this.ManagedPath = this.GetArg(args, "-ManagedPath", string.Empty);
                this.SiteName = this.GetArg(args, "-SiteName", string.Empty);
                this.Sitedefinition = this.GetArg(args, "-SiteDefinitionName", string.Empty);
                this.Owner = this.GetArg(args, "-Owner", string.Empty);
                this.Contact = this.GetArg(args, "-Contact", string.Empty);

                if (this.WebApplicationURL.Length < 1 && !this.CheckSchema)
                {
                    lastError = "You must specify the -webApp parameter";
                    retValue = false;
                }

                this.DirectoryName = this.GetArg(args, "-folder", string.Empty);
                if (this.DirectoryName.Length < 1)
                {
                    lastError = "You must specify the -folder parameter";
                    retValue = false;
                }
            }
            catch (Exception argumentException)
            {
            }

            return retValue;
        }

        /// <summary>
        /// This processes the arguments looking for a specific topic
        /// </summary>
        /// <param name="args">Command line arguments</param>
        /// <param name="token">token to look for</param>
        /// <param name="defaultValue">Default value to be retrieved if token not found</param>
        /// <returns>value of token or defaultvalue</returns>
        private string GetArg(string[] args, string token, string defaultValue)
        {
            string result = defaultValue;
            for (int i = 0; i < args.Length; i++)
            {
                if (0 == string.Compare(args[i], token, true, CultureInfo.InvariantCulture))
                {
                    result = args[i + 1];
                    break;
                }
            }

            return result;
        }

        /// <summary>
        /// Finds a single argument
        /// </summary>
        /// <param name="args">Command line arguments</param>
        /// <param name="token">Token to look for</param>
        /// <returns>true if found otherwise false</returns>
        private bool GetSingleArg(string[] args, string token)
        {
            bool returnValue = false;
            for (int i = 0; i < args.Length; i++)
            {
                if (0 == string.Compare(args[i], token, StringComparison.OrdinalIgnoreCase))
                {
                    returnValue = true;
                    break;
                }
            }

            return returnValue;
        }
    }
}
